/ USB接続 周波数アナライザ PIC18F2550/
#include "./USB/usb_function_cdc.h"
#include "GenericTypeDefs.h"
#include "Compiler.h"
#include "usb_config.h"
#include "USB/usb_device.h"
#include "USB/usb.h"
#include "HardwareProfile.h"
#include <delays.h>
#include <math.h>
#pragma config FOSC=HSPLL_HS, PLLDIV=5, CPUDIV=OSC1_PLL2
#pragma config USBDIV=2, PWRT=ON, FCMEN=ON, IESO=ON
#pragma config BOR=ON, BORV=0, WDT=OFF, LVP=OFF, VREGEN=ON
#pragma config MCLRE=ON, PBADEN=OFF, WDTPS=1024
#pragma config LPT1OSC=OFF, CCP2MX=OFF, DEBUG=OFF
#pragma config CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPB=OFF
#pragma config CPD=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF
#pragma config WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF
#pragma config EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF
#pragma udata
float Freq;
int i, j;
unsigned char mask;
unsigned int Result;
float Para;
union{
unsigned long Phase; // 周波数設定値
unsigned char iPhase[4];
} DDSdata;
float logData0,logData1; // dB値
char input_buffer[64]; // USB入力バッファ
char output_buffer[64]; // USB出力バッファ
char MsgTX[] = "CH0=+xx.x CH1=+xx.x\r\n";
BOOL blinkStatusValid; // USB接続状態表示フラグ
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
void BlinkUSBStatus(void);
void USBCBSendResume(void);
void ProcessIO(void);
void itostring(char digit, unsigned int data, char *buffer);
void serial_out(float data);
void ftostring(int seisu, int shousu, float data, char *buffer);
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = 0x08
void Remapped_High_ISR (void){
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = 0x18
void Remapped_Low_ISR (void){
_asm goto YourLowPriorityISRCode _endasm
}
#pragma code
#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode(){
USBDeviceTasks();
}
#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode(){
}
#pragma code
void main(void){
TRISA = 0x03; // RA0,1のみ入力
TRISB = 0;
TRISC = 0x18; // D+.D-以外全部出力
LATA = 0;
LATB = 0;
LATC = 0;
ADCON0 = 0x00; // AD off
ADCON1 = 0x0D; // AN0,1 Analog Vss-Vdd
ADCON2 = 0xA6; // Right,12Tad,1/64
/*** DDSの設定制御 シリアルモードに設定 ***/
Freq = 10000.0;
RST = 1; // RESET出力
Delay10TCYx(1);
RST = 0;
W_CLK =1; // W0ロード
W_CLK = 0;
FQ_UD = 1; // シリアルモード設定
FQ_UD = 0;
serial_out(Freq); // 初期出力設定
USBDeviceInit(); // USB初期化.
blinkStatusValid = TRUE; // LEDブリンク許可
while(1){
/* USB接続完了待ち */
if(USB_BUS_SENSE && (USBGetDeviceState() == DETACHED_STATE))
USBDeviceAttach(); // USB接続完了
if(blinkStatusValid)
BlinkUSBStatus(); // USB状態LED表示
/* デバイス接続状態なら機能実行 */
if((USBDeviceState >= CONFIGURED_STATE)&&(USBSuspendControl!=1)){
ProcessIO();
}
}
}
void ProcessIO(void){
if(getsUSBUSART(input_buffer,48)){
mLED_1_Toggle(); // LED反転
switch(input_buffer[0]) { // 最初の1文字チェック
case '0':
blinkStatusValid = FALSE; // LEDブリンク禁止
if(USBUSARTIsTxTrfReady()) // 送信可能か?
putrsUSBUSART("OK"); // OKデータ送信指示
break;
case '1':
Freq = atof(&input_buffer[1]); // 周期データ取得
serial_out(Freq); // DDSに出力
break;
case '2':
ADCON0 = 0x01; // チャネル0選択
ADCON0bits.GO = 1;
while(ADCON0bits.GO);
Result = ADRESH*256 + ADRESL;
/* dBに変換 Vref=4.73V 0dB=2.19Vで実測した値 40dB*4.73/1024=0.185 */
logData0 = 0.219*Result - 87.0; // dBに変換(IC特性値)
if(logData0 < 0){ // 負か?
MsgTX[4] = '-'; // -記号セット
logData0 = fabs(logData0); // 絶対値に変換
}
else
MsgTX[4] = '+';
ftostring(2, 1, logData0, MsgTX+5); // 正の値のセット
ADCON0 = 0x05; // チャネル1選択
ADCON0bits.GO = 1;
while(ADCON0bits.GO);
Result = ADRESH*256 + ADRESL;
logData1 = 0.219*Result - 87.0;
if(logData1 < 0){
MsgTX[15] = '-';
logData1 = fabs(logData1);
}
else
MsgTX[15] = '+';
ftostring(2, 1, logData1, MsgTX+16);
if(USBUSARTIsTxTrfReady())
putUSBUSART(MsgTX, 22);
break;
default:
if(USBUSARTIsTxTrfReady())
putrsUSBUSART("NG");
break;
}
CDCTxService();
}
}
void serial_out(float data){ /* 周波数設定制御実行 実際の周波数143.9958で補正 */
Para = 29.82703 * data; // 2の32乗÷144MHz=29.82616
DDSdata.Phase = (long)Para; //* 周波数値32ビット出力する */
for(i=0; i<4; i++) {
mask = 0x01; // ビットマスクの初期設定
for(j=0; j<8; j++){
if(DDSdata.iPhase[i] & mask)
S_IN =1;
else
S_IN = 0;
W_CLK =1; // ビット送信クロック
W_CLK = 0;
mask = mask << 1; // ビットマスクのビットシフト
}
}
mask = 0x01; // ビットマスクの初期設定
for(j=0; j<8; j++) {
if(0x01 & mask) // 6倍モードのみ
S_IN = 1;
else
S_IN = 0;
W_CLK = 1; // ビット送信クロック
W_CLK = 0;
mask = mask << 1; // ビットマスクの1ビットシフト
}
FQ_UD = 1; // 周波数値ロード指示
FQ_UD = 0;
FQ_UD = 0;
}
/ int 数値から文字列に変換/
void itostring(char digit, unsigned int data, char *buffer){
char i;
buffer += digit; // 文字列の最後
for(i=digit; i>0; i--) { // 最下位桁から上位へ
buffer--; // ポインター1
*buffer = (data % 10) + '0'; // その桁数値を文字にして格納
data = data / 10; // 桁-1
}
}
/ Float数値から文字列へ変換 * 合計有効桁は5桁以下とすること/
void ftostring(int seisu, int shousu, float data, char *buffer){
unsigned int i, dumy;
if(shousu != 0) // 小数部桁ありか
buffer += seisu+shousu+1; // 全体桁数+小数点
else // 小数部桁なしのとき
buffer += seisu + shousu; // 全体桁数のみ
*buffer = 0; // 配列最後に\0格納
buffer--; // 配列ポインタ-1
for(i=0; i<shousu; i++) // 小数部を整数に変換
data = data * 10;
dumy = (unsigned int) (data + 0.5); // 四捨五入して整数に変換
for(i=shousu; i>0; i--) { // 小数桁数分繰り返し
*buffer =(dumy % 10)+'0'; // 数値を文字に変換格納
buffer--; // 格納場所下位から上位へ
dumy = (unsigned int)(dumy / 10); // 次の桁へ
}
if(shousu != 0) { // 小数桁0なら小数点なし
*buffer = '.'; // 小数点を格納
buffer--; // ポインタ-1
}
for(i=seisu; i>0; i--) { // 整数桁分繰り返し
*buffer = (dumy % 10)+'0'; // 数値を文字に変換格納
buffer--; // ポインタ-1
dumy = (unsigned int)(dumy / 10); // 次の桁へ
}
}
/ LEDブリンク制御関数* USBアタッチ;高速ブリンク、* USB Enumeration完了:低速ブリンク/
void BlinkUSBStatus(void){
static WORD led_count=0;
if(led_count == 0)led_count = 10000U;
led_count--;
#define mLED_Both_Off() {mLED_1_Off();mLED_2_Off();}
#define mLED_Both_On() {mLED_1_On();mLED_2_On();}
#define mLED_Only_1_On() {mLED_1_On();mLED_2_Off();}
#define mLED_Only_2_On() {mLED_1_Off();mLED_2_On();}
if(USBSuspendControl == 1){
if(led_count==0){
mLED_1_Toggle();
if(mGetLED_1()){
mLED_2_On();
}
else{
mLED_2_Off();
}
}//end if
}
else{
if(USBDeviceState == DETACHED_STATE){
mLED_Both_Off();
}
else if(USBDeviceState == ATTACHED_STATE){
mLED_Both_On();
}
else if(USBDeviceState == POWERED_STATE){
mLED_Only_1_On();
}
else if(USBDeviceState == DEFAULT_STATE){
mLED_Only_2_On();
}
else if(USBDeviceState == ADDRESS_STATE){
if(led_count == 0){
mLED_1_Toggle();
mLED_2_Off();
}//end if
}
else if(USBDeviceState == CONFIGURED_STATE){
if(led_count==0){
mLED_1_Toggle();
if(mGetLED_1()){
mLED_2_Off();
}
else {
mLED_2_On();
}
}//end if
}//end if(...)
}//end if(UCONbits.SUSPND...)
}//end BlinkUSBStatus
//* ボーレート変更関数 USB側とUSARTの通信速度が同じでなければならない/
#if defined(USB_CDC_SET_LINE_CODING_HANDLER)
void mySetLineCodingHandler(void){
//If the request is not in a valid range
if(cdc_notice.GetLineCoding.dwDTERate.Val > 115200)
{ // 115kbps以上なら何もしない
}
else
{
DWORD_VAL dwBaud;
// CDCドライバのボーレート変更
CDCSetBaudRate(cdc_notice.GetLineCoding.dwDTERate.Val);
// USARTのボーレート変更
dwBaud.Val = (DWORD)(GetSystemClock()/4)/line_coding.dwDTERate.Val-1;
SPBRG = dwBaud.v[0];
SPBRGH = dwBaud.v[1];
}
}
#endif
// ***********************************************************
// ************** USB Callback Functions *********************
// ***********************************************************
/*************************************************************
* Function: void USBCBSuspend(void)
*************************************************************/
void USBCBSuspend(void)
{
}
/*************************************************************
* Function: void USBCBWakeFromSuspend(void)
*************************************************************/
void USBCBWakeFromSuspend(void)
{
}
/*************************************************************
* Function: void USBCB_SOF_Handler(void)
*************************************************************/
void USBCB_SOF_Handler(void)
{
}
/*************************************************************
* Function: void USBCBErrorHandler(void)
*************************************************************/
void USBCBErrorHandler(void)
{
}
/*************************************************************
* Function: void USBCBCheckOtherReq(void)
*************************************************************/
void USBCBCheckOtherReq(void)
{
USBCheckCDCRequest();
}//end
/*************************************************************
* Function: void USBCBStdSetDscHandler(void)
*************************************************************/
void USBCBStdSetDscHandler(void)
{
}//end
/*************************************************************
* Function: void USBCBInitEP(void)
*************************************************************/
void USBCBInitEP(void)
{
CDCInitEP();
}
/*************************************************************
* Function: void USBCBSendResume(void)
*************************************************************/
void USBCBSendResume(void)
{
static WORD delay_count;
if(USBGetRemoteWakeupStatus() == TRUE)
{
//Verify that the USB bus is in fact suspended, before we send
//remote wakeup signalling.
if(USBIsBusSuspended() == TRUE)
{
USBMaskInterrupts();
//Clock switch to settings consistent with normal USB operation.
USBCBWakeFromSuspend();
USBSuspendControl = 0;
USBBusIsSuspended = FALSE; //So we don't execute this code again,
//until a new suspend condition is detected.
delay_count = 3600U;
do
{
delay_count--;
}while(delay_count);
//Now drive the resume K-state signalling onto the USB bus.
USBResumeControl = 1; // Start RESUME signaling
delay_count = 1800U; // Set RESUME line for 1-13 ms
do
{
delay_count--;
}while(delay_count);
USBResumeControl = 0; //Finished driving resume signalling
USBUnmaskInterrupts();
}
}
}
/***************************************************************
* Function: void USBCBEP0DataReceived(void)
***************************************************************/
#if defined(ENABLE_EP0_DATA_RECEIVED_CALLBACK)
void USBCBEP0DataReceived(void)
{
}
#endif
/***************************************************************
* Function: BOOL USER_USB_CALLBACK_EVENT_HANDLER(
***************************************************************/
BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
{
switch(event)
{
case EVENT_TRANSFER:
break;
case EVENT_SOF:
USBCB_SOF_Handler();
break;
case EVENT_SUSPEND:
USBCBSuspend();
break;
case EVENT_RESUME:
USBCBWakeFromSuspend();
break;
case EVENT_CONFIGURED:
USBCBInitEP();
break;
case EVENT_SET_DESCRIPTOR:
USBCBStdSetDscHandler();
break;
case EVENT_EP0_REQUEST:
USBCBCheckOtherReq();
break;
case EVENT_BUS_ERROR:
USBCBErrorHandler();
break;
case EVENT_TRANSFER_TERMINATED:
break;
default:
break;
}
return TRUE;
}